package com.zeyu.framework.core.web.servlet;

import com.zeyu.framework.tools.report.convert.Converter;
import com.zeyu.framework.tools.schedule.entity.JobEntity;
import com.zeyu.framework.tools.schedule.job.MonitorMongoDBJob;
import com.zeyu.framework.tools.schedule.job.MonitorMysqlJob;
import com.zeyu.framework.tools.schedule.job.MonitorRedisJob;
import com.zeyu.framework.tools.schedule.job.MonitorServerJob;
import com.zeyu.framework.tools.schedule.job.MonitorWebServerJob;
import com.zeyu.framework.tools.schedule.job.SimpleJob;
import com.zeyu.framework.tools.schedule.service.JobService;
import com.zeyu.framework.utils.Collections3;
import com.zeyu.framework.utils.SpringContextHolder;
import com.zeyu.framework.utils.ThreadUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 初始化的servlet,初始化系统中的各种资源.
 */
public class InitServlet extends HttpServlet {

    // ================================================================
    // Constants
    // ================================================================

    /**
     * UID
     */
    private static final long serialVersionUID = 1L;
    /**
     * Logger
     */
    private static final Logger logger = LoggerFactory.getLogger(InitServlet.class);

    // ================================================================
    // Fields
    // ================================================================

    // ================================================================
    // Constructors
    // ================================================================

    /**
     * @see HttpServlet#HttpServlet()
     */
    public InitServlet() {
        super();
    }

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    @Override
    public void init() throws ServletException {
        super.init();

        logger.info("InitServlet start, config infomation: mysql、mongodb、schedule、activemq、alarmconsole、flow、syslog and so on.");

        /**
         * 检测MySQL的运行启动状态
         */
        logger.debug("check mysql status.");
        checkMySQLStatus();

        /**
         * 检测MongoDB的运行启动状态
         */
        logger.debug("check mongodb status.");
        checkMongoDBStatus();

        // 考虑启动慢问题，加入新线程启动
        ThreadUtils.addExecuteTask(() -> {
            // 启动FTP服务器
            logger.debug("init ftp server.");
            ftpServerInit();

            /**
             * 初始化任务调度
             */
            logger.debug("init schedule quartz.");
            scheduleManagerInit();

            /**
             * ActiveMQ queue 和 subject 初始化
             */
            logger.debug("init active mq queue and subject session.");
            activeMQInit();

            /**
             * 邮件发送管理初始化
             */
            logger.debug("init send email manager.");
            mailSenderInit();

            logger.debug("init convert manager.");
            Converter.getInstance();
        });

        /**
         * <pre>
         * bean trace.
         * // 获取WebApplicationContext
         * ServletContext application = getServletContext();
         * WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(application);
         * </pre>
         */

        logger.info("InitServlet start is ok, some child thread try starting...");
    }

    @Override
    public void destroy() {
        logger.info("Shutdown tomcat,some user create thread not closed, exception ignore.");
        // 尝试关闭所有线程和线程池
        ThreadUtils.serverShutdown();
        super.destroy();
    }

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    /**
     * 启动ftp服务器
     */
    private void ftpServerInit() {
        try {
            // project may not needed.
            logger.debug("apache ftp server init is ok.");
        } catch (Exception e) {
            logger.error("ftp server startup error: ", e);
        }
    }

    /**
     * 检测mysql的运行启动状态
     */
    private void checkMySQLStatus() {
        // 框架使用了Spring，为了保证验证在Spring的Servlet初始化前运行，改用Listener实现
    }

    /**
     * 检测MongoDB的运行启动状态
     */
    private void checkMongoDBStatus() {
        // 框架使用了Spring，为了保证验证在Spring的Servlet初始化前运行，改用Listener实现
    }

    /**
     * 初始化任务调度
     */
    private void scheduleManagerInit() {
        JobService jobService = SpringContextHolder.getBean(JobService.class);

        // 验证系统是否非第一次载入,非第一次载入不再重新加载 job ,因为可能已经修改过
        List<JobEntity> jobEntities = jobService.find(JobEntity.GROUP_MONITOR_MANAGER);
        if (!Collections3.isEmpty(jobEntities)) {
            logger.info("schedule has been initialized. Use the configuration of the database. ");
            return;
        }

        JobEntity job;
        {
            // 数据库监控
            // mysql
            job = new JobEntity(JobEntity.JOB_DATABASE_MYSQL_MONITOR,
                    JobEntity.GROUP_MONITOR_MANAGER, MonitorMysqlJob.class,
                    new Date(), null, 5, TimeUnit.MINUTES);
            jobService.addJob(job);
            // mongodb
            job = new JobEntity(JobEntity.JOB_DATABASE_MONGODB_MONITOR,
                    JobEntity.GROUP_MONITOR_MANAGER, MonitorMongoDBJob.class,
                    new Date(), null, 5, TimeUnit.MINUTES);
            jobService.addJob(job);
            // redis
            job = new JobEntity(JobEntity.JOB_DATABASE_REDIS_MONITOR,
                    JobEntity.GROUP_MONITOR_MANAGER, MonitorRedisJob.class,
                    new Date(), null, 5, TimeUnit.MINUTES);
            jobService.addJob(job);

            // 设备自监控
            job = new JobEntity(JobEntity.JOB_SERVER_MONITOR,
                    JobEntity.GROUP_MONITOR_MANAGER, MonitorServerJob.class,
                    new Date(), null, 60, TimeUnit.SECONDS);
            // 记录历史记录
            job.setHistory(true);
            jobService.addJob(job);

            // web 服务器监控
            job = new JobEntity(JobEntity.JOB_WEB_SERVER_MONITOR,
                    JobEntity.GROUP_MONITOR_MANAGER, MonitorWebServerJob.class,
                    new Date(), null, 5, TimeUnit.MINUTES);
            jobService.addJob(job);

            // 设备指标数据采集
            job = new JobEntity(JobEntity.JOB_DEVICE_COLLECT_MONITOR,
                    JobEntity.GROUP_MONITOR_MANAGER, SimpleJob.class,
                    new Date(), null, 5, TimeUnit.MINUTES);
            jobService.addJob(job);
        }
        {
            // 报表
            // 日报表
            job = new JobEntity(JobEntity.JOB_REPORT_MAIL_PUSH_DAY,
                    JobEntity.GROUP_REPORT_MANAGER, SimpleJob.class,
                    new Date(), null, "0 59 23 * * ?");
            jobService.addJob(job);
            // 周报表
            job = new JobEntity(JobEntity.JOB_REPORT_MAIL_PUSH_WEEK,
                    JobEntity.GROUP_REPORT_MANAGER, SimpleJob.class,
                    new Date(), null, "0 0 1 ? * L");
            jobService.addJob(job);
            // 月报表
            job = new JobEntity(JobEntity.JOB_REPORT_MAIL_PUSH_MONTH,
                    JobEntity.GROUP_REPORT_MANAGER, SimpleJob.class,
                    new Date(), null, "0 0 23 L * ?");
            jobService.addJob(job);
            // 报表归档
            job = new JobEntity(JobEntity.JOB_REPORT_MERGE,
                    JobEntity.GROUP_REPORT_MANAGER, SimpleJob.class,
                    new Date(), null, "0 0 1 1 * ?");
            jobService.addJob(job);
        }
        {
            // 其它
            // 定期清理图片缓存
            job = new JobEntity(JobEntity.JOB_CLEAN_CACHE,
                    JobEntity.GROUP_OTHER_MANAGER, SimpleJob.class,
                    new Date(), null, "0 59 23 * * ?");
            jobService.addJob(job);
        }
        {
            // 数据库自动备份
            job = new JobEntity(JobEntity.JOB_DATABASE_BACKUP,
                    JobEntity.GROUP_DATABASE_MANAGER,
                    SimpleJob.class, new Date(), null, "0 0 1 * * ?");
            jobService.addJob(job);
            // 数据库自动清理
            job = new JobEntity(JobEntity.JOB_DATABASE_CLEAN, JobEntity.GROUP_DATABASE_MANAGER,
                    SimpleJob.class, new Date(), null, "0 0 1 * * ?");
            jobService.addJob(job);
        }
    }

    /**
     * ActiveMQ queue 和 subject 初始化
     */
    private void activeMQInit() {
        // TODO
    }

    /**
     * 邮件发送管理初始化
     */
    private void mailSenderInit() {
        // TODO
    }

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================
}
